import axios from 'axios'
import { message } from 'ant-design-vue'
import { md5 } from 'js-md5'
import { getToken, removeToken } from '@/utils/auth.ts'
import { userStore } from '@/stores/user.ts'
import { User } from '@/proto/user.ts'

const FBHeaderNid = 'x-fb-nid' // nid
const FBHeaderSign = 'x-fb-sn'
const Token = 'token'
// const FBHeaderCT = 'x-fb-ct'

const HeaderFBBrowser = 'x-fb-browser'

const myAxios = axios.create({
  baseURL: import.meta.env.VITE_API_URL,
  timeout: 60000,
  withCredentials: true,
  responseType: 'arraybuffer', // 将响应设置为 ArrayBuffer 不知道为何这样才能正常解析protobuf二进制 自己手动解析会出现某些字节出错问题
  headers: {
    'Content-Type': 'application/octet-stream', // 设置请求头为二进制格式
  },
})

// 全局请求拦截
myAxios.interceptors.request.use(
  function (config) {
    // 做一些请求前的处理
    const nid = 'c68c4ead-e494-40be-a276-d5b5ef4b2c01'
    config.headers.set(FBHeaderNid, nid)
    config.headers.set(HeaderFBBrowser, '1')

    const textEncoder = new TextEncoder()
    const sign = new Uint8Array([...config.data, ...textEncoder.encode(nid)])
    config.headers.set(FBHeaderSign, md5(sign))

    // 设置token
    config.headers.set(Token, getToken())

    return config
  },
  function (error) {
    // 做一些请求错误的处理
    return Promise.reject(error)
  },
)

// 全局响应拦截
myAxios.interceptors.response.use(
  function (resp) {
    // 做一些响应处理
    return resp
  },
  function (error) {
    // 做一些响应错误的处理
    const content = new TextDecoder().decode(error.response?.data).toString()

    if (error.status === 500) {
      message.error('服务器异常了,请联系开发者')
      return Promise.reject(error)
    }

    // 未登录
    if (error.status === 401) {
      if (
        !error.request.responseURL.includes('/user/login') &&
        !window.location.pathname.includes('/user/login')
      ) {
        message.warning('请先登录')
        removeToken()
        userStore().setLoginUserInfo(new User({ name: '未登录' }))
        window.location.href = `/user/login?redirect=${window.location.href}`
      }
      message.error(content)
      return Promise.reject(error)
    }

    return Promise.reject(error)
  },
)

export default myAxios
